package com.hyjx.framework.component.codetable;

import com.hyjx.framework.common.util.SpringBeanUtil;
import com.hyjx.framework.orm.dao.IBaseDao;
import com.hyjx.framework.service.CacheService;
import com.hyjx.framework.service.ConfigManager;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 代码管理类
 *
 * @author bageer
 */
@SuppressWarnings({"unchecked", "rawtypes"})
public class CodeTableManager {
    private static Logger logger = LoggerFactory.getLogger(CodeTableManager.class);
    private static IBaseDao dao = (IBaseDao) SpringBeanUtil.getBean("baseDao");
    private static Map<String, CodeTableInfo> codeTableMap = new HashMap<String, CodeTableInfo>();
    
    public static void init() {
        CodetableModel queryModel = new CodetableModel();
        logger.debug("开始加载代码表" + new Date());
        codeTableMap = new HashMap<String, CodeTableInfo>();
        Map<String, String> configMap = ConfigManager.getAllConfig();
        for (String key : configMap.keySet()) {
            if (key.startsWith("sys.codetable.")) {
                String sql = configMap.get(key);
                int temp = sql.indexOf("???");
                if (temp == -1) {
                    logger.debug("开始加载代码表" + key);
                    try {
                        List list = dao.queryObjectList(queryModel.getModuleName() + ".querySqlTableList", sql);
                        CodeTableInfo codeTable = new CodeTableInfo();
                        codeTable.setCodeList(list);
                        codeTable.setCodetable(key);
                        codeTableMap.put(key, codeTable);//.replaceAll("sys.codetable.", ""
                        
                        //支持简名访问
                        String shortKey = key.substring(14);
                        CodeTableInfo codeTable2 = new CodeTableInfo();
                        codeTable2.setCodeList(list);
                        codeTable2.setCodetable(shortKey);
                        codeTableMap.put(shortKey, codeTable2);
                    } catch (Exception ex) {
                        logger.error(ex.getMessage());
                        continue;
                    }
                    logger.debug("结束加载代码表" + key);
                }
                CacheService.set(key, sql);
            }
        }
        List<CodeTableInfo> tableList = dao.queryObjectList(queryModel.getModuleName() + ".queryTableList", null);
        for (CodeTableInfo codeTable : tableList) {
            logger.debug("开始加载代码表" + codeTable.getCodetable());
            codeTableMap.put(codeTable.getCodetable(), codeTable);
            logger.debug("结束加载代码表" + codeTable.getCodetable());
        }
        List<CodeBean> codeList = dao.queryObjectList(queryModel.getModuleName() + ".queryCodeList", null);
        CodeTableInfo codeTable;
        for (CodeBean codeBean : codeList) {
            codeTable = codeTableMap.get(codeBean.getCodetable());
            if (codeTable == null) {
                logger.error("加载代码表" + codeBean.getCodetable() + "，在管理代码表中没有配置。");
            } else {
                codeTable.getCodeList().add(codeBean);
            }
        }
        logger.debug("所有代码表加载结束：" + new Date());
    }
    
    /**
     * 得到代码表的所有名称
     *
     * @param tableName 代码表名称
     * @return
     */
    public static List<CodeBean> getTableList(String tableName) {
        if (tableName == null || "".equals(tableName)) {
            return null;
        }
        CodeTableInfo codeTable = codeTableMap.get(tableName);
        if (codeTable == null) {
            return null;
        }
        List<CodeBean> list = codeTable.getCodeList();
        List<CodeBean> list2 = new ArrayList<CodeBean>();
        List<CodetableModel> list3 = new ArrayList<CodetableModel>();
        for (Object cb : list) {
            if (cb instanceof CodeBean) {
                if ("#".equals(((CodeBean) cb).getParentCode()) || StringUtils.isEmpty(((CodeBean) cb).getParentCode()))
                    list2.add((CodeBean) cb);
            } else if (cb instanceof CodetableModel) {
                if ("#".equals(((CodetableModel) cb).getParentcode()) || ((CodetableModel) cb).getParentcode() == null)
                    list3.add((CodetableModel) cb);
                list2.clear();
                for (CodetableModel cm : list3) {
                    CodeBean cb1 = new CodeBean();
                    cb1.setCode(cm.getCode());
                    cb1.setCodetable(cm.getCodetable());
                    cb1.setName(cm.getName());
                    if (StringUtils.isNoneEmpty(cm.getOrderid())) {
                        cb1.setOrderid(Integer.parseInt(cm.getOrderid()));
                    }
                    cb1.setParentCode(cm.getParentcode());
                    cb1.setValidflag(cm.getValidflag());
                    list2.add(cb1);
                    
                }
            }
        }
        return list2;
    }
    
    /**
     * 通过代码得到名称
     *
     * @param tableName 代码表名称
     * @param code      代码
     * @return
     */
    public static String getNameByCode(String tableName, String code) {
        if (tableName == null || "".equals(tableName)) {
            return null;
        }
        CodeTableInfo codeTable = codeTableMap.get(tableName);
        if (codeTable == null) {
            return null;
        }
        if (code == null) {
            return null;
        }
        List<CodeBean> list = codeTable.getCodeList();
        for (CodeBean bean : list) {
            if (bean.getCode().equals(code)) {
                return bean.getName();
            }
        }
        return null;
    }
    
    /**
     * 根据名称取码值
     *
     * @param tableName
     * @param name
     * @return
     */
    public static String getCodeByName(String tableName, String name) {
        if (tableName == null || "".equals(tableName)) {
            return null;
        }
        CodeTableInfo codeTable = codeTableMap.get(tableName);
        if (codeTable == null) {
            return null;
        }
        if (name == null) {
            return null;
        }
        List<CodeBean> list = codeTable.getCodeList();
        for (CodeBean bean : list) {
            if (bean.getName().equals(name)) {
                return bean.getCode();
            }
        }
        
        return null;
    }
    
    /**
     * 得到下级代码表列表
     *
     * @param tableName  代码表名称
     * @param parentcode 上级代码值
     * @return
     */
    public static List<CodeBean> getSubCodeList(String tableName, String parentcode) {
        if (tableName == null || "".equals(tableName)) {
            return null;
        }
        CodeTableInfo codeTable = codeTableMap.get(tableName);
        if (codeTable == null) {
            return null;
        }
        List<CodeBean> list = codeTable.getCodeList();
        List<CodeBean> resultList = new ArrayList<CodeBean>();
        for (Object bean : list) {
            if (bean instanceof CodeBean) {
                CodeBean cb = (CodeBean) bean;
                if (cb.getParentCode() != null && cb.getParentCode().equals(parentcode) && "1".equals(cb.getValidflag())) {
                    resultList.add(cb);
                    //resultList.addAll(getSubCodeList(tableName,bean.getCode()));
                }
            } else if (bean instanceof CodetableModel) {
                CodeBean cb = new CodeBean();
                CodetableModel cm = (CodetableModel) bean;
                cb.setCode(cm.getCode());
                cb.setCodetable(cm.getCodetable());
                cb.setName(cm.getName());
                try {
                    cb.setOrderid(Integer.parseInt(cm.getOrderid()));
                } catch (Exception ex) {
                
                }
                cb.setParentCode(cm.getParentcode());
                cb.setValidflag(cm.getValidflag());
                if (cb.getParentCode() != null && cb.getParentCode().equals(parentcode) && "1".equals(cb.getValidflag())) {
                    resultList.add(cb);
                }
            }
        }
        return resultList;
    }
    
    /**
     * 获得代码表存储数据对象
     *
     * @return
     */
    public static Map<String, CodeTableInfo> getCodeTableMap() {
        return (Map<String, CodeTableInfo>) ((HashMap) codeTableMap).clone();
    }
    
    /**
     * 重新加载代码表
     *
     * @param codeTable
     * @return
     */
    public static boolean reloadCodeTable(String codeTable) {
        CodetableModel queryModel = new CodetableModel();
        logger.debug("重新加载代码表开始" + codeTable);
        try {
            String sql = null;
            Map<String, String> configMap = ConfigManager.getAllConfig();
            for (String key : configMap.keySet()) {
                if (("sys.codetable." + codeTable).equalsIgnoreCase(key)) {
                    sql = configMap.get(key);
                }
            }
            
            if (sql != null) {
                List list = dao.queryObjectList(queryModel.getModuleName() + ".querySqlTableList", sql);
                CodeTableInfo codeTableInfo = new CodeTableInfo();
                codeTableInfo.setCodeList(list);
                codeTableInfo.setCodetable(codeTable);
                codeTableMap.put(codeTable, codeTableInfo);
            } else {
                CodetableModel codetablemodel = new CodetableModel();
                codetablemodel.setCodetable(codeTable);
                List list = dao.queryObjectList(queryModel.getModuleName() + ".queryList", codetablemodel);
                CodeTableInfo codeTableInfo = codeTableMap.get(codeTable);
                if (codeTableInfo == null) {
                    logger.error("加载代码表" + codeTable + "，在代码表明细中不存在。");
                } else {
                    codeTableInfo.setCodeList(list);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        logger.debug("重新加载代码表结束" + codeTable);
        return true;
    }
    
    /**
     * @param key
     * @param cti
     */
    public static void addCodeTable(String key, CodeTableInfo cti) {
        codeTableMap.put(key, cti);
    }
}